{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b3ad1c9c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "from torchvision import transforms\n",
    "from torchvision import datasets\n",
    "import matplotlib.pyplot as plt\n",
    "from PIL import Image\n",
    "import numpy as np\n",
    "import cv2 \n",
    "import os\n",
    "os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6ce9dd81",
   "metadata": {},
   "outputs": [],
   "source": [
    "class CNN(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(CNN, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)\n",
    "        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)\n",
    "        self.fc1 = nn.Linear(320, 50)\n",
    "        self.fc2 = nn.Linear(50, 10)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = nn.functional.relu(nn.functional.max_pool2d(self.conv1(x), 2))\n",
    "        x = nn.functional.relu(nn.functional.max_pool2d(self.conv2(x), 2))\n",
    "        x = x.view(-1, 320)\n",
    "        x = nn.functional.relu(self.fc1(x))\n",
    "        x = self.fc2(x)\n",
    "        return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "08412611",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "CNN(\n",
       "  (conv1): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1))\n",
       "  (conv2): Conv2d(10, 20, kernel_size=(5, 5), stride=(1, 1))\n",
       "  (fc1): Linear(in_features=320, out_features=50, bias=True)\n",
       "  (fc2): Linear(in_features=50, out_features=10, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 加载保存的模型\n",
    "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
    "model = CNN().to(device)\n",
    "model.load_state_dict(torch.load('model.pth', map_location=device))\n",
    "model.eval()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "5f746420",
   "metadata": {},
   "outputs": [],
   "source": [
    "#加载图片并转换为灰度图，同时进行二值化处理。\n",
    "def preprocess_image(image_path):\n",
    "    # 使用 OpenCV 加载图片\n",
    "    image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)\n",
    "    # 二值化处理\n",
    "    _, binary = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY_INV)\n",
    "    return binary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "cf2068a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用轮廓检测算法分割数字\n",
    "def segment_digits(binary_image):\n",
    "    # 查找外轮廓\n",
    "    contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n",
    "    # 存储每个数字的边界框\n",
    "    digit_bounding_boxes = []\n",
    "    for contour in contours:\n",
    "        # 获取轮廓的边界框\n",
    "        x, y, w, h = cv2.boundingRect(contour)\n",
    "        # 过滤掉过小的噪声\n",
    "        if h > 10 and w > 5:\n",
    "            digit_bounding_boxes.append((x, y, w, h))\n",
    "    digit_bounding_boxes = sorted(digit_bounding_boxes, key=lambda x: x[0])\n",
    "    return digit_bounding_boxes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "2a872843",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 根据分割的数字边界框裁剪数字并使用模型进行预测。\n",
    "def predict_digits(binary_image, bounding_boxes):\n",
    "    predictions = []\n",
    "    for box in bounding_boxes:\n",
    "        x, y, w, h = box\n",
    "        # 裁剪数字区域\n",
    "        digit_image = binary_image[y:y+h, x:x+w]\n",
    "        # 调整到 MNIST 的大小 (28x28)\n",
    "        digit_image = cv2.resize(digit_image, (28, 28), interpolation=cv2.INTER_AREA)\n",
    "        # 转换为 PyTorch 张量\n",
    "        digit_tensor = torch.tensor(digit_image, dtype=torch.float32).unsqueeze(0).unsqueeze(0).to(device)\n",
    "\n",
    "        # 使用模型预测\n",
    "        with torch.no_grad():\n",
    "            output = model(digit_tensor)\n",
    "            _, predicted = torch.max(output, 1)\n",
    "            predictions.append(predicted.item())\n",
    "    return predictions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "1dc3e230",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAigAAACQCAYAAAAiC5C0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAA9hAAAPYQGoP6dpAABRrElEQVR4nO2dd1wT9//HX5dBEkLYsmSKgCgOBNFaZ7VK1VpH3avab91aF+5WsSquOn8urFq1rta92qq1rqptxYWIG3EilY2EzM/vD0xKJIEkhAz7efq4x0PuPnf3fieXu/e9P+/BEEIIKBQKhUKhUKwIlqUFoFAoFAqFQnkbaqBQKBQKhUKxOqiBQqFQKBQKxeqgBgqFQqFQKBSrgxooFAqFQqFQrA5qoFAoFAqFQrE6qIFCoVAoFArF6qAGCoVCoVAoFKuDGigUCoVCoVCsDmqgUCgUCoVCsTosaqCsWbMGQUFB4PP5iIqKwrlz5ywpDoVCoVAoFCvBYgbK7t27MW7cOMyYMQNXr15F8+bN8dFHH+Hx48eWEolCoVAoFIqVwFiqWWDjxo3RsGFDrF27Vr0uPDwcXbp0QUJCgiVEolAoFAqFYiVwLHFSqVSKpKQkTJ06VWN9u3btcOHChTLjJRIJJBKJ+m+lUons7Gy4ubmBYZgql5dCoVAoFErlIYSgoKAAPj4+YLHKn8SxiIHy6tUrKBQKeHp6aqz39PRERkZGmfEJCQmIj483l3gUCoVCoVCqkCdPnsDX17fcMRYNkn3b+0EI0eoRmTZtGvLy8tQLjVOhUCgUCsV2EYlEFY6xiAfF3d0dbDa7jLckMzOzjFcFAHg8Hng8nrnEo1AoFAqFUoXoE55hEQ+KnZ0doqKicOLECY31J06cQNOmTS0hEoVCoVAoFCvCIh4UAJgwYQIGDBiA6OhovPfee0hMTMTjx48xfPhwS4lEoVAoFArFSrCYgdKrVy9kZWVhzpw5ePHiBSIiInDs2DEEBARYSiQKhUKhUChWgsXqoFSG/Px8ODk5WVoMCoVCoVAoRpCXlwdHR8dyx9BePBQKhUKhUKwOaqBQKBQKhUKxOqiBQqFQKBQKxeqgBgqFQqFQKBSrgxooFAqFQqFQrA5qoFAoFAqFQrE6qIFCoVAoFArF6rBYobYqgQHQGICPpQUxggwAFwHYXFUaCoVCoVBMz7tloPABfAvgAoBi0x6ax+fBjmuH9rHtERYaptc+Fy9dxNkzZyGXyys4OIDmANoCeF1ZSSkUCoVCsX3eLQOFQckDfh6A3MofjsVigcUqmQWb/c1s9OreC9WqVYMD46DX/jm1cjBg3gAcO3YM5RbsdQSwp/LyUigUCoXyrvBuGSgmwt7eHjweD9OmTUOLFi0AAEFBQfDw8DDoOM7Ozli2bBk8PDywbdu2ij0pFAqFQqFQAFADRQM2mw0Oh4N58+ahZ8+ecHFxgUAgMPp4DMMgJCQES5cuxdOnT/Hbb79BqVSaUGIKhUKhUN5NqIECQCgUQigUYsSIEejatSv8/Pzg6upa4X6EEOTm5kIqlarXiUQi2Nvba4xzcnLCunXrEB8fj507d0Imk5lcBwqFQqFQ3iX+0wYKh8MBl8vFhAkTMGbMGDg4OOjlMSGEQCqVQiaT4bPPPsOFCxfU2+bMmYNBgwZpjOdyuahRowZWrFiB9PR0nD9/HgqFwuT6UCgUCoXyzkBskLy8PIKShFzNxR4Ex0HgrGXbW4uzszOZOHEiuX37Nnn16pXe5338+DF5/PgxGTRoEAkNDSUCgUDjuB4eHiQ0NFRj2bx5MyGEEKVSSdLT00m/fv2Ig4PDv/s5vpFbWLHcdKELXehCF7rY+pKXl1fhM/c/60GZNm0axowZU6HHhBACsVgMuVyOlStXYsmSJQCA169faw16zczMRGZmpsa6jIwMyOVycDgc+Pn5Yf369fDy8sLy5cupJ4VCoVAoFC38Zw0UHo8HOzs7ndsJIVAoFFAqlRg5ciROnz6NvLw85OXlGXyuJUuW4L333kPLli3BMAyEQiGmTZuGpKQknD59uhJaUCjvMCwAvjD/XSoTQKGZz0mhUMrwnzVQli5dCqlUirFjx4LH42lse/36NSQSCebPn4+zZ8/i7t27RhkmKrKzsyEWizXWubi4lAmmpVAopagDYDuANCP2ZQA3NzfUrl0bLBYLd+/eRUZGBoiSlL+fM4DzAGYYcU4KxRJ4Agi3wHmVAJJQpcVF/7MGyuPHjxEfHw8fHx/06tULHA4HhBDIZDJMnz4dP/30E3JyclBcbOKStIbgC0BkudMbTR6A55YWogpgAAShpPKvtZIL4IWlhTARAgCXAXxu4H5MSebcoWOHEOMYA4Zh8MD5Adp0b4Nnz56Vb6S0BNDTeJEpFLMzHiUGypOKhzIMAzs7O1TzqIYOHTqoC5ECwKt/XuHo0aOQK+SQSfXING0IYAmAfUbKrQf/WQMFKPGUTJ06FS9fvkS/fv1ACMH06dNx4MAB5OTkWFY4ewA7AbwCYER9N5GjCAKBADWCasDVTb+U6Tt37qCwsBAFBQUQF4kr3EcrXAAOADoCkBh3CKvFH8B+APdQEualJwzDwNXNFWw2W+f28FrhsBdqetTkcjlSbqYg42UGFHI9YpXsUGI8fQzgXcpkN+CzBgAXZxfs378fDRs0BIdVcourEVgDhw8exv/+9z9cuXJFd2VnWqaIYmvwAPwfgBO6h7DZbLi6uiI4OBirVq2Cs7MzgtnBYBhGPaZIVIQHjR7g+vXrmDBjAv75558yx3BwcPh3NmEmSu45Vch/2kABgKdPn+Krr75CQkICACAvL8866pSwAIgBDARQYNiuPD4P3yz8Bn379oVIJCozhaUNQgjya+RDJpNhzpw52LRxEwCgWFIMpcKAu7YrgF0o2yc7GCUl/a2V5wBeVjDGDsADlLxh6/ORMACfz4eD0AFHjx1FUFCQ9mEMAycnJ3A4mj9HpVKJl4Ev0WlUJ1y/cb3i78EDwNaS8/6XEQqFqFWrFvh8vnodh8NB/fr1sW3bNjRt2hS5ubmWE9CWEQAIRdnft6VRALiDd++lyASwWCyEhYXh2LFjcHR0hLOzs4ZhosLe3h5169ZFrVq1ULNmTcTGxqqNERaLhfDwcEyePBnDhg0rE7JQVfznDRQAKCoqQlFRkaXF0I6Bb48sFgurVq5Cjx494OzsrPd+DMPA2alk/Fczv8LoUaOhUCjw2WefISkp6V9xCCm/r5Aqiaw0IpTEEjxCyY1ET1Tux+joaPj5+Wlsu3LlCtLT001TmVeEkmmpAXqM1abfW6jk5vF42LVrF8LDwxEQEFBuULY22Cw2vDy9sGfPHgwYMECj3o5O2f7j8Hg8rF69Gm5ubmW2MQwDR0dHDbc2xUA+QcmUwn3Dd1V97iKRCK1bt9bwKL5+/RqnTp3SKHppELUAfA3gqHG7v8vUr18fu3fvhp+fn17XPpfLRWRkJJYsWYLhw4dDoVAgMjISu3btgqenJxwdHdGrVy9IzGANUgPlHcHe3h5sNhuff/45unfvbpBx8jYeHh7w8PAAIQSJiYnIz89Xb1u9ejV+/vlndeq1XrAB5AMYAkAPO9De3h4CgQDLli1DQEAAwkRh8OBp9kG663oXL2UvkZCQgOPHj1fOUAkHEG/87ipUFYlXrlwJb29vsFgsNGjQAA4O+jWX1AaLxUJQUBCWLl2KgQMH4v79+7Rdgg6EQiG2bNmC1q1bl/FGUUyEPYCfUBJ7oAcsFgv2QnuEhIRgyeIl4HA4sLe3RyQvEiz2vw9LsUKM0/anMXTcUDx79sxwuWajxLtD0YDD4cDNzQ1BQUHlGicymUztFWGz2bC3t0e3bt3AZrMxceJEuLm5ITAwEBwOB23atEF8fDxmyWZVuZFCf8U2jqp/0JYtWxAdHQ0XFxc4OTlpHatKnS7XA1LquKoHbGnq1KmDgoICTJw4EYcOHdL7ePrAZrNhZ2eHXbt2oV69evD29tbpdQgLC0NoaCiCg4PRoUMHJCcnm0wOY7C3t8e+fftQq1YteHt7g8vlmuzYDMOgUaNGOH78OLp27YqrV6+a7NjwgfXc2DNh8HRmafh8Pho1agSRyBYjy98dGIZRe0dCQkKwb98+ODk5wcvLS+vUAlDy+2nfvj02b96Mrl27QiIpefDRBquVIzY2FomJiTrj35RKJRQKBU6dOoVhw4YBAGJiYrB161Y4Ojqib9+++OCDD8Dj8dTHcHBwwOjRo5Epy8TSEUurVH5qoNgwQqEQixcvRnR0NGrVqqXzxkwIQWFhISQSCaZNm4Zr166Ve1yGYTB37lxER0dDJBJpPGzd3Nzg6uqKRYsWYcqUKYiPj8dvv/2mvqEYi7OzM5YsWYL69eujVq1aenkdGIaBt7c3tm/fjokTJ+Lvv/8GUOIuNtpVbCTffPMNmjVrplfquOr70DfWydHRERwOBz4+PnB3dwfDMKYxxtwBHATwAmDAwNnZGWG1wirVIBMA5DI5Um+nIjsrW39vjxOAvwHEGXfOkJAQbNy4EZ6ensYdgFJp2Gw2HB0dERYWhqVLl4LD4YDP5yM0NFSvqQU2m433338fp0+fBiEEz58/x8iRI1FYWKjhxaXoR2hoKBYuXKjVMJTL5cjPz8e1a9cwbdo0ZGdnIz09HUBJWYzmzZsjJiYG8+bNg7+/f5n9hUIhnIlzletADRQbJi4uDoMHD9YIBnwb8qZv0KhRo3Dy5ElkZWXp9fDu06cP7O3tsXPnTkRHRwMomZtks9lgGAbBwcGoUaMGtm3bhsmTJ2PTpk1GPzT5fD4OHDiAJk2a6BXQWxoWi4U6depgx44daiNp7Nix2Ldvn1k9Kv7+/uV+D8C/34VSqcSwYcP0KtLH4/Hw888/o1atWuBwOFizZg2aN2+OjIyMygvNRUmWWA/A0d4RJ0+dRB3nOpX2/igUCjzxfoKPhnyEe/fuVVx7BACaAhhk+Lm4XC6EQiG2bt2KmJgYGl9iQWrXro2DBw9CJBLBzc1Np7ekPOzt7dX3G7lcjsuXL+POnTv45JNPIBaLTZ/AwAVQA5YL+lWgpM6PidVisVhwcnJCcHCw1u/h+vXr6Nq1K16/fo3s7GyNbQUFBbh8+TKSk5Nx//59HD58WKsnm5gh6I0aKGZAJBIZHCBZEU5OTvD29q7QOMnOzsawYcNw/PhxFBTo7z/Pzs5GdnY2Bg0aBHt7e7VXJSYmBsCb1FlXV7i6umL27Nl4+vQpzpw5g2IYVzeGxWKVe0MjhCAvLw8SiQTOzs4oLi7WiCR3cXGBm5sbCCFYtGgRXr58ibt37yIrK8ss7QSmTZsGX19fREZGahhZ5E3Ha4lEgtevX2Po0KHIzMzEo0ePUFhYcblSPp+vvikzDAN3d3d4enri1atXpnF/E5RkJCkBVql/lYHFZiHALwD79+7HyJEjce7cuYo9KUaE1XC5XOzYsQPh4eGoWbOm+Y0TZwDvwfoyWipCCeBPANkVDdQfVcf2gIAAvb4HpVKJvLw8ODs7QyaTIScnR/1CwWaz4ebmBg6HA29vb7i4uOCPP/5AamoqxowZg8zMTNO9fLQA8C2Ae4CrqyuaNGlS7n1IKpUiJSUFEokE2dnZlZcjBMCXAM5U7jClYbPZaN++PZYtW6b1ZaO4uBgvX77Eixcvyr2HSCQSvHr1yqJT59RAqWJ4PB6mT5+OZs2ameyYfD4fK1euRI8ePXSOIYRAIpFg8uTJOHjwoNEPs4cPH6r/379/f7WhxeVysXfvXsTExKB69erYvXs3Ro8ejR0/74DSwKdNcXExunTpgh9//BEtW7YsE+AokUggl8sxatQonDhxAlu3bsXBgwfx008/ASh5cG/ZsgWxsbHqoNLDhw+jsLAQnTp1QnJycpUHlt6/fx8dO3bEzp070bZtWzAMo5b7888/x9mzZ9XGSmVkcXR0xM8//4y2bdvi1q1bJpM/Pz8fsbGxOHLkCKKioox6+y0Nm81GeHg4tmzZgg8++ABpaWkmv9GxWCzUrFkTderUMelx9aYDgC9QMjVlIAzDgC/gw8XZBT169ACHW/GtWCKRYPfu3SgsLCwxzo39OBugJNB1g5H7vwXDMBCJRBUGYqpQKpV4+vQpxo0bh40bN+LGjRvo2bOn+kXCy8sLJ0+ehKenZ8nnxOcjIiICYWFh6vTX/Px80xTRtAfwM4BpQO3mtbHr2C4IhUKd17/SToncWrl4+PAh2n/aHjnZlayXteSNDCYkMDBQPd35th5KpRLHjh3DkCFDbCO+R682vlaGKboZm2tZuXIlyc7OLqODQqEgHTp0KBmnrZuxw5t1DprHY7PZZOfOnSQ/P1/rZ6NUKolcLicSiYT07duXiESiKtPN39+fnDx5Un3uJ0+ekMg2kSVyC0qNdX6ji335x/P19SUHDhwgSqVSrYdcLieTJk0iISEhRCgUEgCkevXqxNHRUWPf4OBgcvfuXaJUKjU+4wcPHpAmTZoQhmF0nzscBD/qoXMICPaCgNE9JjQ0lDx8+JDIZDIycuRIEhISQuzt7Y3+jPl8Prlx44bGdywWi0m9evXKjq8Ggl9AYKfn8b1BcAwE3JK/GYYhkZGRJDMzs8x3oM9S+rNXIZfLSWpqKqldu3b5srwHgsS31sWAYJPufXg8HklKStJ6Xl08ffqUuLq66pajBQjW6Pn5DQLBZOO+1+rVq5PLly+Thw8fEoVCoZfscrmcPHjwgPzxxx/Ezc2NsFgswmKxDD//KBCMNE5uDAHBJM11/v7+5Pr160Qmk2mV++3r6O7du6ROnTrE3t6e1KxZk/j5+Wkcj8PhkG7dupHi4uIy15dUKiX37t0jx44d0/xdzQbBp0bo8zEIEkr+LxAISGxsLCksLKzwmpJIJOT7778nbDbb6N82AIIlIPioEvsDBMtA8OG/f4eHh5PCwkKtcqemppLAwEC9jx0dHU2Ki4u1HiteGU/Q23i5aTdjC8Pj8eDv7w8XFxeTHVMgECAoKEhnQGxxcTFmzJiBv//+Gzdu3DBoWsdQHj9+jNev/23E4OPjgxXLV6CbrBte4ZXBx3v69CmmT5+O6tWrIzAwEOPGjUN6ejru3r2r0SFaWxpiWloa+vXrh+XLlyMiIgJCoRBsNhtBQUFYv349Zs6ciaNHj5rFk9KzZ0/w+XykpqYiKyurSs9nSgghuHnzJnr06IG1a9fC2dkZo0aNKlNRUhscDgeLFi1CWFiYep2DgwPYbDZCQ0OxcuVKdO/evVI9rd5GKpVi0qRJ2LJlC3x8fHRmKlgTDMPAzc0NK1euRP369Q1Kh2az2ahRowZ8fX1x+PBhyOVyFBYWYtSoUXj1quT3Rt4EYJsTLpeLoKCgMrqoZMnOzsbIkSPVga5isRipqalQKpW4f79sQRW5XI4TJ06gTZs2ag+Aq6sr1qxZA0dHRwQHB8PHxwe7d+/G0KFD8eKFaXo7iMVinDlzBr169UJiYiK8vb11elLs7OzQuXNnbN68GePHj4dYLLaKWlr16tVDYmKi1ql/uVyO7OxsvT+vJk2aYPXq1VqniWQyGSQKM1TFq9CEsUJsxYMyceJEnZassR6UJUuWaLVolUolkclkJD4+nvD5fLPpePDgQQ05skgW8bnpY5QHRbV4eXkRPz8/wuVyDZbH09OTBAcHkytXrqjfTJVKJXn+/Dlp2LChdk+KCT0opl7M6UFRLQzDEB8fH+Lr62vQG6KXlxfx9/cn/v7+JDw8nKSlpallzsjIIN7e3rr3N8KDAoCwWCwSEhJC7ty5o37DLs8jYUkPCofDIV5eXuTq1atEKpXqe7srF4VCQZ48eUIePXpEHj16RC5cuEBcXV0Jh8PRLYuJPSjBwcFaPbo5OTkkJiaGVK9e3ThPT6mFzWYTX19f8v7775OcnBy1V+bnn38mAoGAIB6V9qCUvqbat29PCgsLiUQiIVKpVKdHRSKRkPT0dHLgwAHj7rsm9KAwDENatWql05N19uxZ4uPjo/dxP/74Y52/paNHjxKnJU5V7kGxtfAum0EoFMLLywtCoVBjPSEEBQUFyM7ONjgVViQSwdvbW2emy1dffYU1a9aYrcGhk5OTSet9qMjIyMCTJ0+Mith/+fIlHj58iP79+6srrzIMA09PT2zbts2ksUDvKuRNiufTp08NCjDOyMjA48eP1Uvp78/V1RV79+6Fv7+/SWVVKpV48OABRowYgdu3b+PTTz/F5cuXtXrKVL89cxe6c3Jygr+/Pw4dOoSff/4ZderozpRSKpXIzc1FVlZWuUt2djYUCgVYLBZ8fX0REBCAgIAANGzYECdPnsRPP/0EHx8fODpapr+EQqFAdnY2Hj9+jGfPnlX6M1coFHj69Cn+/vtvxMXFQalUgs1mo3nz5tizZ4/WysHGolQqce7cObRo0QLvv/8+evbsiRcvXmj9HsRiMfz8/NCmTRv8+OOP8PDwqPgEVUSbNm2wdu1arZ5EhUKBf/75R2/vSWBgIObNm6fTg1RUVGRSb6gu6BRPFTFv3jwMGTJE67ZJkybh0KFDBjUk5HK52LhxIzp27FhmG3nThfnevXt4+bKihjKmgcPhYOfOnWjdurVZzmcIhBA8ePBAY3pL1UuiMhV2KYahSqlmsVjgcrmoV68eHB0dTVfH5Q1KpRKnT59Gy5YtkZ2djdu3b+P8+fOoVq2axrji4mJ88cUXZrmxqnBxccHRoyV9mKpVq6ZzGoq8SUEvKCjARx99hKdPn5Z7XHt7exw9ehSBgYHg8XjqBwmPx0NkZCTq1q2LJk2aICUlBV27dq3SqV5tPH36FO3atdOYmjUFUqkU9+7dU/8tFArRrl07fFb8Gb49/a3JzlNUVIQrV64AAK5evYqLFy9qfVjXqlVLnVr90UcfYe3atejXr5/ZXhJL4+rqirCwMK2Bsffu3cOXX36p1+9O1RtMV4qyOaEelCqAYUqKXumKE8nNzUVGRoZBxc0mTpyI2NhYrYXAFAoFvvjiC5w8edJomQ1FNZdeUe0PS6CqrPv+++9bWpT/LGKxGD169MCNGzfU6wQCAX788ccy1YlNgVKpxD///KN+c9f1xm6S1FA9cXd3x6FDh9CwYUN4eXmVa5yIxWL07NkTLVu2xPXr15GRkVHu8ujRI3zyySdo06YNMjIyoFQqoVQq1bpxOBx4eXmhadOmOHDggM7q0lWFQqFAZmZmlXir3n5ocjicMp3ATYlCocDLly+1fg+XLl1Cly5dkJeXBzabjXbt2mHHjh1WdV+8ceMGunXrhufPn+s1PioqCrt27bIKHaiBYmIYhkFCQgI+/PDDMtsIISguLjY4vUsVbKvL4FmxYgUOHTpk1jdDOzs7qy2KpSokZyn3NuXft7bSgYMsFgshISF6Vdt9F3BwcECtWrXKLT6oVCqRkZGBAQMG4LfffsOtW7f0mtpUKpW4e/cu/vrrL/Tq1QuxsbH45JNPcO/ePbx+/RqvX79GUVER+Hw+mjZtiu3btyMgIMCU6pkdVQmB+Pj4MvcexkItvIuLi3HhwgVMmzYNCoUCDg4O+PDDD/H111+b9QHPYrG0XmdyuRxZWVm4e/euXsZi69atsWbNGoSFhVnF/Z1O8ZgYFouFqKgo+Pj4lNmmVCoxZMgQHD9+XP8DMsDSpUvRp0+fMpsIIVAqlUhJSTF7+/g5c+YgIiJCqzyWpqKib7bEu6SLJSFv+lCZC4FAgLVr15abwUcIQVpaGj755BPcvn3bKPnkcjnOnTsHoMQwT05OVtcqcnFxweHDh1GtWjXExsZiy5Yt+Pjjj1FQmYZHBmDqB1xERAT27NmjderBHFVNdSGRSHD16lW198rBwQFjxoxBaGgoevfubZZ6I+G1wzF33Nwy60+ePIkvvvhC72vLy8sL0dHRFRbNNNd93vIm0jvGmDFj1KWa30YsFiM9Pd2gNEAejwc/Pz+tsROEEEyePBnHjh0zVlyjsLe3h6+vb5k3BIVCgSlTpqhTHi2Bvb09Zs2apZHuCpR8Vq9fv7aN4kRv8PLywq5duxAUFGRpUWye/Px89OnTB48eParyc4lEIuzcuRPNmzfXOq2jCtbNyMjA6NGjkZqaahLjiRCC9PR03Lt3D/fu3cOVK1cwfvx4yGQysNlsxMTEqINnqxpVGrC7u7tJjqeqXB0YGGgVb/Zvo1AoUFhYqGGk+Pn5me3lgs/jay3MVlhYWGE8kwoWi6VXH6779+9j7ty5MIdNaH3ftA3DZrMREhKiMxBzzpw56sArfRk7dizatGmjdZtCocDNmzfNFhgLlFzEmzZt0hmsm3IrBVKJeRv1qeDxeNiyZQvGjh1bptmgXC5H37599ep/Yw3w+Xx89913+Oijj8pkgtkKHA7HIt4fbbVFZDIZLl++bJZaFQKBAI0aNdL6vamMk48//hgxMTE4ceJElb2NyuVypKSkqI8vEAjQtm1bjBo1yqTnIYRALpdrxPaoOkubYjpP1ShzzZo1Wr9ba/Dc3rhxA507d9aoC8UwjEF1biwJwzBo0KBBieFRAYWFhbhz544ZpKIGiklZuHAhPv300zLrCSEghCArK8vgrr/Ozs5af+SEEKxcuRKXLl0yWl5jUKXsWttDk8/nY/v27Wjfvr3OB0NGRoZG/x5rxd7eHrt370arVq1s5gb3NgKBADt37kTdunXNel4ul4tly5bB1dXVrOdVUb16dezbt0+r54C86Y3VtWtXXLp0yeA0blPAZrPh6GTa2Kxnz56hW7duZTynjo6OWL58ucENQEvj5OSEw4cP4+jRowgJCSk7tUMIXrx4gR93/2j0OUyBVCrFixcvNIy02rVrY/fu3eaJudLyHmBIMHizZs2wbds2rV4YS2Kbdz8rgsvlgsVioW/fvujbt6/OPPj4+HiTZdkQQrBw4UIkJiaatQ05l8vF8OHDy8SeqFi5cqXZLOu34fF4iIiI0BpIrErDtvRblj7w+XzMnj0bbdq00WloSSQSizbwqggXFxesWbMGH374odkNWYZhEBISUiX1efTBwcEB9erV09oc9NmzZxg5ciTOnz9vcA0kYzHH5yCRSHDjxg0UFRWBEKJ+wInFYmzfvt2oekYMw8Df3x/Lly9Hq1atdAacPnjwAGPGjEFa87RK6VBZVNWSS0+RCIVCREREVHmFY4ZhMGDAgDLfdVpaGr79tuLUa39/f8ybNw/h4eFWZZwA1ECpFCwWC+vWrUNMTAw8PT3L1F1QoVQqcenSJTx+/LjS51R5Y/7++2+kpZn3R7l8+XL07t1b59vp9evXkZuTa1aZgJLvYdGiRQgMDCyzTfV5xcfHm7S5nqlRNUXbuXOnTuMEKIml6Nq1q0YtCGuDz+ejbdu2Vudlq2ocHBywevVqnR7P/Px8nDx50mzGiYuLC/7v//7P5J3UtZGXl4fRo0djz549ao+JTCbDpUuXjHoxqFevHnbs2IGwsLBy07NzcnLw22+/Qd7EsrFlrq6u+OCDDyzm8QwPDy/ThTwvL0+vkAJHR8cKA2MtBZ3iMRIej4dx48ahS5cuiIiI0GqcqNKKV69ejcuXLxt8DobFlLGKlUolxo8fj/PnzxstuzEIBALUqFFDq3GiquNgiQBUoVCItWvXolu3blpdyYQQxMXFYdu2bVY7vSMSibB69WocOXIEbdq0KRM/A5ToUVRUhIKCAty5c8cihaD0wc7ODgkJCVpTvFXXibk9WarfYVV6ndzc3PDDDz/gvffeK/NAVdVomTp1qsFTvJWBzWabLahUoVDg4cOHeP36tfpzFolESEhIMMhAEggE8PPzw9KlS1GrVi2dxolSqcTz588xffp0iwa+MwwDX19fzJs3zyZ6QZWGYRg0btwY69atM4sRawzUg2IELBYLK1euRK9evSosgDRp0iT88MMPRtUo8fX1Re+o3hrrVN4TU1doLA8ul4sdO3agefPmWrcrFAoMHToUR44cMesVxWKxsHDhQgwaNEincSKXy3H58mVkZGSYTzADcHR0xKFDh9C4ceNy6yYUFRWhc+fOSEtLM2tQtKFwuVw0bNhQ6w1PLBajW7duuHr1qlllksvlGg31qgKBQIDmzZtr9Z48f/4cHTt2xK1bt8xqnJn7gXn//n107NgRR44cgaurq/pa0FcOVWE7Ly8v+Pv7azWsVOniDx48QJcuXXD37l2LTXeqGmHu27cPISEhOg1Ba8w6AoCAgABs3bpVa2yPtWCdn5yVM2zYMHz66aflGidFRUXIz8/HkydPjC6gxuVwraI0u729PQICAnS67FesWIHDhw+btZy2UCjEunXr0KtXL51BeBKJBIMHD8a1a9fMJpchODo64ttvv63QOAFK3hjT09ORlpZm9sBKfVGlRdeoUaPMNqVSifz8fKSlpZnd+6PqLVRVn5udnR2WLFmiM/4pLy8PaWlpZn3T9/Pzw+7du8vUYVEqlZAUV40XRyqVIikpCePHj0dubi4IIWCz2XBwcND6AGSxWHB0dISjoyPCw8OxZ88eREVFISgoSKdR8+LFC3To0AF9+vTRu/iYqXhb3l9++QXbt29HaGioTnk9PT0xc+ZMqzIAOBwOYmJisGvXLqsoZ18e1INiIKqW57riMFQW/vTp07Fv3z6L1gQxBRwOBwsWLECdOnV0jnn48KFZq9iy2Wx88803GDhwoE7jRNXb5MqVK2YNJNYHDocDgUCAgwcPokmTJjqNk9LpmzKZzKoDY/l8PjZs2IDY2Fit8/BZWVmIjY1Fenq6BaSrWlQB2toCUouKijB06FCDah+ZAgcHB0RHR5fxZOXl5WHDDxuq7LwymQy7d+/GgwcPcOTIEdSoUQO//PILYmNj8c8//2iMjYiIwN69e2FnZ6cuza/L26D6LRQUFODSpUtm7y3E5XJRu3Zt7NmzRy95VWRlZWHDhg1W9dtt164dNm7caHUZO9owyIOSkJCARo0aQSQSwcPDA126dCmTtUEIwezZs+Hj4wOBQIBWrVohJSVFY4xEIsGYMWPg7u4OoVCIzp07611MxtLEx8ejf//+ZdargjGVSiXGjh2LH374AU+ePLHauAd9YLPZWLt2LXr27FnmRqfSV7WYC4ZhsGLFCgwYMKBc44QQgpkzZ5qlMJchcLlcfP/99zh9+nSFxkleXh4+/vhjNG3aFG3atMGzZ8/MLK1+VJQWrTLanz17ZlOF8vTByckJe/bs0eo1Ut0PMjMzzfobcXBwwMqVK7VeWwqFosoNdqlUisuXL6NLly7Izc1F3bp1sWLFCg0DzsXFBatXr0aNGjXg7+8PHx+fch/2r169QmxsLD799FONWiPmICAgAKdOncKOHTv0lleFh4cH4uLiqnyaR9t9mGGYMgZISEgIFi9erNM4efu+bmnDyiAPypkzZzBq1Cg0atQIcrkcM2bMQLt27XDr1i21+3/RokVYunQpvv/+e4SGhmLu3Ln48MMPcefOHbULdNy4cTh8+DB27doFNzc3TJw4EZ06dUJSUpJVBhqp0mvbtm2rbvyljSVLluDChQs4f/48srKyzCyl6Rk5ciS6du2q1Vukqhp77949JCcnV7ksdnZ24PF4mD9/Pnr06KGzzoRUKsWyZctw4cIF/Pnnn1YVTOrs7Izly5ejU6dOOqcHVd4SqVSKmTNn4vTp02YNrDQUfdKiX79+ja+//trqPFmmgMPhoG7dumUqcBJCkJmZiS+//FLvFvemwt7eXuu0g1KphFQqNctDRyqV4uLFi5g6dSqWL1+O2NhYrF+/HhMnToSLiwuWLVuGRo0aVfjgVqXVFxYW4urVqwZ1gNcXNpsNDq/kUejr64sFCxZovJA5ODigSZMmRmXo8Hg8dOnSBTKZTB0krbpPmQpCCLZu2YrmPZtDIBCoDY+goCDs2bNHYxrM0dFRa8djoOT6OHXqFFauXAkAiI6OxldffaUxRqFQmC0LDQBAKkFmZiYBQM6cOUMIIUSpVBIvLy+yYMEC9Zji4mLi5ORE1q1bRwghJDc3l3C5XLJr1y71mGfPnhEWi0V++eUXvc6bl5dHUFJoV3OxB8FxEDhr2WbEwjAMYbFYZM2aNSQrK6tcmZRKJUlPTyd9+vQhDMNoLBWey/GN3MJS6xxAgu4HkTxlnsZ5ZDIZee+990yiX0W6f/fddzr1LS4uJtHR0WX3dQHBryAQlFrn/EY/e+Nk4XA4ZPv27SQlJYWIxWKdMsnlcjJw4EDi6Oho2DnCQfCjHuNCQLAXBIzhnyWHwyE7duwgUqm03OtILpeTIUOGkNq1axOBQFDuMctcW9VA8AsI7PSUzRsEx0DANe76EAgE5ODBg6SwsFCnPnl5eaR169aEz+eXf8z3QJD41roYEGwyTC4ej0eSkpI0ZJBIJNqvVW1LCxCs0fN8g0DcFrqR58+fa/19dOrUibDZbKOueWMXb29v8ueffxKJRFJGpvT0dNKwYUPC+ZJDMNLIcwwBwSTDvo/mzZuTrKwsIpFIyK1bt8jdu3eJQqEo93egVCqJQqEgWVlZpGXLliQ0NLT8z3I2CD41Qp+PQYZkDiHJyckkOTlZL9mMQSwWk5SUFJKcnEyOHz9ORCJRyfmXgOCjSn7vy0D4nflk/PjxRKFQEKVSaZSMN27cIIGBgerjdujQocxnce7cOVKzZs2Se89MEPQ2Xu68vDwdkvxLpWJQVHEHqjfstLQ0ZGRkoF27duoxPB4PLVu2xIULFzBs2DAkJSVBJpNpjPHx8UFERAQuXLiA9u3blzmPRCLReIs0x5sYl8vF9OnT0axZMzRo0KDCypSqwkI+Pj5YvHgx6tevr962ceNGHD58WGO8VCqtsIBRxosMHEw+iAFdBmisFwgEYLPZVRL0x+PxwOVy8fXXXyM2NlbrGEIIlixZgrt375r8/KURCARgsVgYP348OnbsWG5QMnmThnv//n2reVNXfZazZs1CZGQkoqKiKiycxWKx0KdPHxw9ehRisRj29vZl3na4XC4WL14MLy8vjB8/Hg8fPjRbsCCfzwePx8OCBQsQGhqKmJgYnZ4TsViM/Px8s6VFC4VCfPfdd6hZs2aVn6s8yBuvkbkDmnk8Hr799ltERkZqvc6kUinu3r0L+Xvmm2aTSqW4efMmZs+ejaVLlyI8PFznWNVvmBCCO3fuYPr06SguLsalS5eq9K3d1cUVddzrGBWPoVQqIRaLNbxSqp42pY/H5/NRu3ZtAEBwcDAWLFiAyZMn4zVjmumqYnExtm/fDrlcjvnz50MoFBqkj1wuR3Z2doXTyIWFhXjw4IHZpn6MNlAIIZgwYQKaNWumriyqSuX09PTUGOvp6akOjsvIyICdnV2Z6HJPT0+dqaAJCQmIj483VlS9YRhG7XIcMWIEJk6cqDUyvzymTJkCoVCokW5Yv359zJkzR2PcokWL8N1335V7LLFYjMePH0OpVKrlYrPZ2LRpE4YOHWpYV2Q9YLFY+Pbbb9GuXTv4+PhoffAolUp1B+WqNAQEAgH27NmDkJAQeHp6aq2rAUA9z19UVITu3bsb3OuoqmCxWFi6dCk+/PBDVK9eXa9y1+RNIOD333+PvLw8uLq64tChQ2WqEzMMAz8/P3C5XISHh6N3795G1dkxFC6Xi02bNqFRo0Zam0WWpqioCJ988gkePnxotrRoDoeDpk2b6rxWqgJtD4G8vDx06tTJ7MX07Ozs0LBhQ63Giep3Yk7YbDaCg4OxZ88eODs7Vzh9n5OTg44dO+LVq1coLi42W1zin3/9CUlDCXg8nkEPdUIIbt++jR49emgYUCEhIfjpp5/KxMipni8CgQCDBw9GSEgIutzvgiKYpj9UZmYmNmzYgNTUVOzfv18vI4W8iQ/7/fff8fnnnxtV9bcqMdpAGT16NG7cuKG1YJi2fgn6fFC6xkybNg0TJkxQ/52fnw8/Pz8jpC6fsWPHokePHgBK0vQMNU4AaC3YVq1atTLrp0+fjpSUFFy8eLHc423YsAHN6jdDy5YtAZTMASYkJCApKclg2cqDzWZj9erV6N69e7kdSJcsWYKDBw9WufckPj4erVq1qvDBLpPJMHToUNy+fRs3btywipgTNpuNNWvWoHv37nBzc9N7P4lEgi+++ALt2rXDiBEjwOFwEBkZWW4RpRo1amDFihXo2rUrMknV1cbh8XjYvHkzOnToUGHtH9XDUJUW/S7Tt2/fMt+xQqFAenq6WefqXVxcsH37dvj7+5fZpvJMTJgwwSzNEgHA29sbW7Zsgbu7O2rXrq1XbKFCobBInZ+rV66i37f9sHXrVq0eSxVvew3+/vtvDB8+HKmpqRrbnj17hrZt25aJr2natCkWLVoEoOQFrFmzZvgk4hPsPLzTZLoUFxfj/PnzmDlzJpYuXVrheFVa+KtXr/DkyROTyWEqjDJQxowZg0OHDuHs2bPw9fVVr1cFj2ZkZMDb21u9PjMzU+1V8fLyglQqRU5OjoYXJTMzE02bNtV6Ph6PV6mGU6VhsVjqH0unTp3Qu/e/hdAaNGiA0NBQk5ynIgIDA7Fw4ULMnTsXJ/48AQLtLrP09HRkZ2drrEtNTS2zzlg4HA6mTp2KevXqoXXr1jqNE5Wlfe/ePVy4cMEk59YmC4fDwaxZs9C3b98KjRNCCNasWYNDhw6VGzynravu291XKyu3KmJ+6tSpiIiIwAcffGCQcaI6Tv/+/REZGamzp9PbMAyD6OhorF+/HnGL43CfuW+MCjoRCASYPXs2goOD8eGHH5brnSBvAnxzc3MRFxdnFcXxVDJVlUvap7oP7GD5Kpz29vaIjo4uE6wLANnZ2Rg3bhxOnz5d5V6UatWqYcGCBfD09ESrVq0M6gXk6OiImTNnYvLkyWbNfiwsLMSvv/6K+fPn4+uvv4adnZ1WT0J6ejpmz56t3vby5UutRQfFYrHWJq5vzxoIBAJ48bQnXFSG4uJi7N69G8+fP69wbGZmptmrkhuCQQYKIQRjxozB/v37cfr0aQQFBWlsDwoKgpeXF06cOIHIyEgAJXOQZ86cwcKFCwFAPQ9/4sQJ9OzZE0BJ8Z2bN2+qrcuqZMSIERg8eDCAkmml0gaWOWEYBs2bN8e6devw6ZBPcQW6pybIm3QvhmHAZrOxfv16jBo1CqdOnaq0HOPHj0dcXFyFDx7VlN6BAwcqfU5tsFgsrF69GtHR0QgLC9O7j0tsbCzWrVun00BRHTcqKkq9TqlUYvTo0fjrr78qLTeHw8HGjRvVdWJCQkKMnmLgcDhaY7AqgsvlonPnzqhWuxo+zvsYOdBtrBmCg4ODOn1Ynymq/Px89OrVC8+fP8etW7esoqDc69ev0bt3b6SmplpalCojMDAQu3bt0lnUUSwW48iRI1WenhscHIydO3ciMjJSr4yXt41GHo+HIUOGoGbNmujVq5dZY8lev36tbna6YsUKDBw4ELm5uRpjioqKcOfOHYun3upDRkYGfvrpJ0uLUWkMMlBGjRqFHTt24ODBgxCJROo3JCcnJ3VQ0Lhx4zB//nyEhIQgJCQE8+fPh729Pfr27ase+/nnn2PixIlwc3ODq6srJk2ahLp166Jt27YmU4zL5Wq4Fbt27Yo+ffqgVq1aCAkJqdSxZTKZyeo5eHl5IT4+HkOchuAf/KN1TEJCAhiGQefOncFmsxEWFgYPDw/w+XxIpVK934pUHgo2m405c+YgJCQEERERFRonYrEY06ZNw+7du01aeE71HU2dOhVRUVFo0qRJudNLb6PqXJuYmKizUBzDMGWOSwjBggULMHjwYDx+/Fin96o8+Hw+Zs2ahbp166Jp06Zl3o6qAvImPfHt77uoqAiTJk3Cc9lzvP5f5R5CdnZ2YLFYYLFY+Oabb9C6dWutb+XaZBOLxbh+/bpVeE5UKBQKpKSkmG1qw5wwDAMXFxcsXrwYUVFRZYwC8iZFt6rT1BmGgZubG5YsWVJhaXuVTIQQPHr0CNOnT0dwcDDi4+PBZrMhEAjQsmVLzJ07F1OmTLGIJ2XgwIFm7ThN0Y1BBsratWsBAK1atdJYv3nzZnz22WcAoHbPjRw5Ejk5OWjcuDGOHz+uEc+xbNkycDgc9OzZE2KxGG3atMH3339vshooDIvB/Pnz8dFHH6nXubu7lwne1QeV96A0K1euxKZNmyotpwqlgxK5i3J1CABcvnwZo0aNgoeHh3oabNGiRZgxYwZGjBiBP/74Q0Pet1FNb0ydOhW9e/cGwzAIDAys8K1Y9SCcMWMGEhMTTRrfwTAMEhISEBsbC39/f6PifYCSeI8WLVoYfO4WLVrg559/Rt++fXFNes2AnQGBvQC7d+7GBx98UOUde0tff3K5HIMHD8b169c1xqh6k8hd5MAAbUfRDx6Pp+4gq7pG9DFOVLJ9+eWXyM7O1jvQ0BbeRK0Zb29vHDx4EPXr19fqscjJyUGXLl2QkZFRpd4If39/7Nu3D3Xr1i238zAhBAUFBejWrRsyMjJQXFyMtLQ08Pl8HDt2DK6urti/fz/c3d3x+eefIyQkxOyF2QoLC03imaaYBoOneCqCYRjMnj0bs2fP1jmGz+dj1apVWLVqlSGn14tq1aohcV8imoQ10VlQTR+kUqm6qNHcuXM1siTu37+Px48fm0LcEhwBVGCsv3jxAqNHj0Z8fDw6duwIPz8/+Pr6YtWqVRpF4TZv3qwxDaMqVR8SEoKwsDC9prTIm+6vK1aswIkTJ3Dz5s1KGycMi4FAKFBHss+dOxe9evUyymg0BSpPVGJiIqZumYpT0O+mFBUVhUVHFqFxo8YmNU5Un/nb0yJSqRSTJk1Ceno6CCFISkoy7cPmjcHlyHfEqlWr8OGHHxplLLLZbEyaNAlDhw7Va7xMJkNcXBxSUlJs2lCRSWVQcpQWaQgnEokQGhqqNc5DqVSioKAAt2/fLlNi3lQwDIMGDRpgxYoVqFevnlYjSZVhd//+fUyZMgXFxcX4888/Nbw6YrEYqamp4HK5mDBhAlatWgUnJye0aNECO3fuxPDhw/WKp7BmGIYxWRzlf4l3rhcPj8dD8+bN4cYyLECxNAqFAmvXrlUbUC9evLAKF/G1a9cwfPhwHDx4EFFRUWCxWGjQoIHGmPr162sYhwzDoHr16hU2owP+zb5QKpUYOXIk9u7da7KeF0GBQThw8QAEpOSNvHr16nq/nZsSlY6qh2JkZCS+DvgaF/68gGJUbIS5uLigZcuWYDOV8/a9LQchBGPHjsXvv/9eZtzTp0+rzN0stBfi4OGDCKoeBH9/f6OqZQIlsT6NGjXSezwhBN7e3mjXrp1ZO3Obmu+//x5DuwzVCGpWxYpVFWw2G/b29li/fr1OIzk9PR2dOnUyWTC9Nry9vbFt2zbUrl1bp9fswYMH6Nq1K/Ly8ipMG5bJZPjxxx/x8OFDHDt2DE5OTujQoQM2b96Mrl27WsU92FhUJeYphvHOGSiZmZn48dqPGN57uME57SoWLlyIdevWWWXa1YsXL/D5559jxYoV6qm20nq6u7sbFMehQqX/119/jdOnT+PWrVsmbchlZ2eHGr41IGSqbkpEnzdxqVSK//3vf3j48KF6XVFgEaTd9DMALl++jEv8S2japKnR1xfwb6fl0p641NTUKinlXR6BQYGIqRYDEd+4KTZjYRhG3Xytf//+eAwTeiTNSG5uLhQKhUaZBJFIhJ07d2LgwIEa15kpCAwMxMaNG2Fvb4/69euXMYRU15lUKsWjR4+qLFA5ODgYW7du1Vk2vbQcDx8+1DuWRCqVIj09Xf2ZstlsvP/++9i1axf69+9vNUUYDSEyMhIbNmxAQECA1TfnszbeOQNFKpVi1f+tQm2f2mjWrJnWH7BCoSgTaLhixQr8/fffAEoeQtZonKhITk7GjBkz4Ofnh7i4OERGRhr8xvb255CYmIizZ8/i4sWLVVIg6WXmSzwmjxHmG2YSd7iqqFnpB79SqcT8+fNx+/ZtnfspFAqcPHlS80aXA6CLfufNzc3F12u+xneJ3yEgIECrLrpkmzt3rrp+jEKhwIkTJ8zelfVtsrOzkc3JhtBTaPZpCi6Xi/feew/z58/HyB9GIp+xvYdPQUEBxowZg2XLlqlrMxUXF+P77783aT8uDocDBwcHzJ8/Hy1atNDp6crKykJcXBxevnxZZcGxIpEI8+fPR+PGjbXed5RKJV68eIHp06fj5cuXBnv/srOzsWDBAiQkJIDNZkMoFCIqKgp8Pt8mDRRXV1c0aNDAKvvMWTvvnIECFpD6MhWfTfoMcXFx6lRmFQQE8XPjy9TySHuYpplWZvwMkeGIABh47V68eBEXL15EUlISFi9ejC5duqi36VMUjxCCKVOmqKcUtNVbMSW5ObnoPqw7NqzYgKZNK+d9AEoe8MOGDcO1a9c01t+9e7dqg+q4wO/Jv+PjwR9jxYoVGi0NSss2YdIEzdRWAty9dxevC0vJZgfTXmeuMLA/eUkth86fd8a2TdtQt25do9/wjI0jYbPZ+PTTT6ForMCQc0OggOVTkw1BKpXi6NGjGpWupVIpjh07pjOzzFCEQiF27NiBgIAAhIeH6zROVCX29+/fb7Jza4PH46FFixY6H7i3bt1C//79kZycbFTdFbFYjHPnzkGpVKrP4e7ujmXLlmHQoEE21RFb1frEEjFK7wLvloEiA/AEwHrgEXmEKQ5TMCd5TplhuW1yIWlmRR1iGQDPUCJ/aewA1AFQzvP2AR5g9p7Z2PjXRgBAhw4d0Lx583JP9+NPP+Lq1au4fOMyXsreVG30ebNUFicAWmozETuCVFYqJmyegGF2wwyKV1DJq3E8QnDxwUXkyN6aEtEszaMfNaDfgz0PABcgPxCkIAU95D1gl1y2SBchBDndcsxfNpoF4B5gyDNeqVAiOTkZcXFx2LRpE7y9vcFisXSmNOtCoVDgq6++Mrq8e054DpS1zFuK3ZSoUmcZhoFIJMKGDRswcuRIdYsPY+DxeHBzc8OKFSt0dotWQQhBfn4+Zs6cWeVZL927d9eaVq9UKiGRSJCTk4OUlBSTFoWzs7NDcHCw1U+RsFgs2NnZITo6GlOmTIG9vT0iIiLKyK3qCixn246xZQnePQPlC6i9EYVv/tkECgClr1UJgIsAJmgfXpobb/4BwK///Ar2wfLdMTKWDMpIJRBprLAVcA6aWUlFAP4GMAn4C3/hypMrYD/X32WklvdtGlZSThUMgJN6jMsE0PnNeMBkBdFMigIGGSjgAsST4GTKSbQf1B7r1q9DcHAwFEoFJk6ZiJs3b+p1GEIIHqU9Mr5uBQtAmHG7WhqJRILRo0fj6NGjcHZ2hp2dHT744AM4OTmBYRiDvEuqB5mzszP27dsHb29vBAcHlxu8TAjBq1ev0KVLF1y+fLnKPQzBNYPBQ9mMlAcPHqBXr17Izc21KS+HKYmJiUFiYiKcnJzg5+en06C6evUqhgwZgmcTym/O91/n3TJQgJKH/Lvw25ABmGb4bvI3/6wKKYBJ//5plTLqy7tUu6kQJfE3GwAllEhBCjpmdgQ7mw0QoODjAsg/MtP3xAGw3zynMjWq9O/evXtj8+bN8PHxAZfLRWJiIl69eoVhw4ZV2CUWKJnG+O677yASicDlchETE6NXauqTJ08wZMgQ/P333xZt9lZcXIzU1FSr6IdlCby9vbFkyRKtHpO3KSoqKqm2nGVbU5rm5t0zUCgUin4UAOgDtUcIAPJhwSBEE9yr386oMRdSqRSnTp1CfHw8vv32WwiFQjRu3BgymQyrVq1SB3fm5+fj66+/1giOFolEmDNnDry8vBAbG6uXUUIIQWZmJmbNmoWMjAycPn3aYq0FCCHIy8vD4sWLra4bbmVgs9l6dYF2c3NTf38xMTEVXnuvXr3C8uXLzd5d2hahBgqF8l/mHXqBKywsRJ8+fbBlyxaEhZl/vkgul2PLli14+PAhduzYAXd3d3C5XHTt2lU9RiqVokmTJhoPci6Xi/r165fbtVqFarpILBZj6NChOHr0qMV7Hj179gz9+vXDxYsXLS6LqQgLC8P69etx69YtjB49WqcxoUq3jomJqXAaTkVhYSF+++03my5QaC6ogUKhUKwWFosFNlf/eKWUlBSNIFGGYcDlcstUW62qN32JRIKzZ89i2LBhWLx4Mfz8/MDlctVv1XZ2dgYFiKtQdWV++vQpvvrqK4jFYpw6dcoqDILi4mJcuXLF5r0nqmvEyckJ8+fPR/PmzVG7dm3IZDLMmDFDnbYdGhqKmTNngs1mw8nJSWe6tQqlUon09HTMnDkTUqkURUVFNl10zpxQA4VCoVgtsbGx+ObSN3qPZ7FYCA0NVf8tFAqxf/9+jZogRUVF6NOnT5XU+wFKvCQHDhxAamoqXF1dsWPHDvj7+xs87VT6DfvZs2fo3bs3srKyLN9Rl5SUa7D2jBpDqF69Onbu3AmhUAgul4vw8HCwWCxUq1YNQ4cORYsWLdReFAcHB4SEhOhVzgEAkpKSMHjwYNy6dYt6TQyEGigUCsVqcXV1RaRnJBgY9zBks9moU6eOxjq5XI6tW7eiqKgIUqkU48ePr1Q6sDYIIbh9+zbYbDYmT56MTZs2Gdy7KT09HePHj1e/dV+6dMkqPCZ79+7F/9r8zywdvM1BSEgIVm9ejffee0/rNA2fzy/TUkQf7t27py6al5KSYgJJ/3tQA4VCoVgtly9fRppnGoKCgkz2xs7hcNC6dWsAJcbKq1evMHHiROOq+ooAeOverIACx64dw9iEsbCzs4NQKMTw4cNhL9TdSTw7OxsbEjcgIyMDhy8f/tco8dC5i2E4oqSmj5Fcv34dS64uwezZs7U2KqwsLi4uGDVqlNkqrzo7O6Nl85ZG96EqjaoI5o0bNzB37lwcOXKEBsNWAmqgUCgUq+XOnTv434z/4ccffzSqx1RFcDgcDBw4EAEBARg8eDCew4CuufcBDARQQUhJIQqxCZsAlMTEbLy5EQxLt7GlVCiR1zAPIAA+0l8cveECmG/87sXFxThy/Ai++uorkxsoNWrUwHfffYdmzZrZZPXVq1evYvLkycjMzERycrKlxbF5qIFCoVCsFkII/vjjD4wdOxbz58+Hr6+v0cdis9lavTA8Hg+tW7fGrFmzMOHgBLwur3Rzaf4A0N4wGQgIcpFr2E5VQSXL2zx58gRxcXGYN28ePDw88O2332L69OnIzc3VKzW3NCpPiUgkQnx8fLll9KuCh2kPMeXIFHzzzTcQCoV6eepUvcwAICcnB7NmzcLr16+RkZGB3377rapF/s9ADRQKhWK9cAGpQIpdv+xCyrMU2NvrnhopD0dHR6xduxaurq46z/PJwE9Q0KIAk89MhhJ6PmBttN5gZcnJyUFiYiIKCwuxYcMGDB48GA0bNoRMJsOtW7cwfPhwvarJenh4YNu2bRCJROBwOFo7NAPG93rSh6xXWVi7di3EYjFWr14NFotVbodmoMRA++yzzyAWiyGVSnH9+nWriA9616AGCoVCsU6yAQQC2FvieVC1czAGFouFZhnNwP6n/DdzCSOB8g6NGdAHqVSKQ4cOQSAQYMGCBYiKigLDMAgLC4Ozs7NeRoVAIECrVq0qrAGTk5OD+fPnV00JfVdAEiDB3pt7waxiMGrUKK1TVy9evMC6desgV8hRWFCIsy/PQiF/Y5QEG3nudyPOuMqgBgqFQrFO7gP4EAZ3aNaGEkq8wAv9BltRH1FrJzs7Gxs3bkRKSgr27NkDd3d3uLq6onv37iY7ByEEYrEY58+fN70n5T6AagAWAK/wCutZ67Hl1BatWWNKpRLFkaXK+Lc2wfkJgIcmOM47CjVQKBSK9fLfbOtiU0ilUly8eBFTpkzBunXr9KqIawjp6ekYMWKEcVlWFZEKoJQtRUAghpENL42FlkbRCTVQKBQKhVIpZDIZDh48CDabjeDgYEyYMEEdlKxa9KF0gO2rV68wf/58vHjxAidOnKi6GA9qIFgt1EChUCgUiv7YAXAouzpbmo3vdpV0Y/7l/C9gWAz8/fyxdOlS2PH086o8evQIkyZNglQmhVgsxuW/L5cYJgI9ZKK8c1ADhUKhUCj68RzAMAAf6B5SgAKcwRkAANeOi3PPzpVb96U0UqkUz0Y9MzzWxBHAz4btQrF+qIFCoVAoFP34FcB5QN/OAzLIkIa0qpSoBALoW76GYjtQA4VCoVAo+kEAFFpaCMp/BdurJUyhUCgUCuWdhxooFAqFQqFQrA5qoFAoFAqFQtHg5s2bSEhIqJrqvXpCDRQKhUKhUCgaPH78GPv27bNojyFqoFAoFAqFQinDo0ePSvoPyeVV2rBRF9RAoVAoFAqFUobs7GzMmTMHo0ePVlf4NSc0zZhCoVAoFFuGiyqrpptdmI09h/aALWCj9QetS85DYBbrgSGW8NtUkry8PDg7O1taDAqFQqFQLMtkAH1Q5fVp7Hh28PL0wuPHj0tWuAL4EsBJ446Xm5sLJyencsfYpIHy8OFDBAcHW1oMCoVCoVAoRvDkyRP4+vqWO8Ymp3hcXV0BlEQZV2SB2SL5+fnw8/PDkydP4OjoaGlxTA7Vz3Z5l3UDqH62zLusG/Du6EcIQUFBAXx8fCoca5MGCotVEtvr5ORk019URTg6OlL9bJh3Wb93WTeA6mfLvMu6Ae+Gfvo6FmgWD4VCoVAoFKuDGigUCoVCoVCsDps0UHg8HmbNmgUej2dpUaoEqp9t8y7r9y7rBlD9bJl3WTfg3ddPGzaZxUOhUCgUCuXdxiY9KBQKhUKhUN5tqIFCoVAoFArF6qAGCoVCoVAoFKuDGigUCoVCoVCsDmqgUCgUCoVCsTps0kBZs2YNgoKCwOfzERUVhXPnzllapApJSEhAo0aNIBKJ4OHhgS5duuDOnTsaYwghmD17Nnx8fCAQCNCqVSukpKRojJFIJBgzZgzc3d0hFArRuXNnPH361JyqVEhCQgIYhsG4cePU62xdt2fPnqF///5wc3ODvb09GjRogKSkJPV2W9ZPLpdj5syZCAoKgkAgQI0aNTBnzhyN9uq2pN/Zs2fx8ccfw8fHBwzD4MCBAxrbTaVLTk4OBgwYACcnJzg5OWHAgAHIzc21mG4ymQxTpkxB3bp1IRQK4ePjg4EDB+L58+c2oVtF+r3NsGHDwDAMli9frrHe1vVLTU1F586d4eTkBJFIhCZNmvzboA/WrZ/JITbGrl27CJfLJRs2bCC3bt0iX375JREKhSQ9Pd3SopVL+/btyebNm8nNmzfJtWvXSMeOHYm/vz8pLCxUj1mwYAERiURk7969JDk5mfTq1Yt4e3uT/Px89Zjhw4eT6tWrkxMnTpArV66Q1q1bk/r16xO5XG4Jtcrw119/kcDAQFKvXj3y5Zdfqtfbsm7Z2dkkICCAfPbZZ+TPP/8kaWlp5OTJk+T+/fvqMbas39y5c4mbmxs5cuQISUtLIz/99BNxcHAgy5cvV4+xJf2OHTtGZsyYQfbu3UsAkP3792tsN5UusbGxJCIigly4cIFcuHCBREREkE6dOllMt9zcXNK2bVuye/ducvv2bXLx4kXSuHFjEhUVpXEMa9WtIv1Ks3//flK/fn3i4+NDli1bprHNlvW7f/8+cXV1JXFxceTKlSvkwYMH5MiRI+Tly5c2oZ+psTkDJSYmhgwfPlxjXa1atcjUqVMtJJFxZGZmEgDkzJkzhBBClEol8fLyIgsWLFCPKS4uJk5OTmTdunWEkJIbEJfLJbt27VKPefbsGWGxWOSXX34xrwJaKCgoICEhIeTEiROkZcuWagPF1nWbMmUKadasmc7ttq5fx44dyZAhQzTWdevWjfTv358QYtv6vf0QMJUut27dIgDIpUuX1GMuXrxIAJDbt29XsVYllPcAV/HXX38RAOoXOFvRjRDd+j19+pRUr16d3Lx5kwQEBGgYKLauX69evdS/O23Ykn6mwKameKRSKZKSktCuXTuN9e3atcOFCxcsJJVx5OXlAfi3M3NaWhoyMjI0dOPxeGjZsqVat6SkJMhkMo0xPj4+iIiIsAr9R40ahY4dO6Jt27Ya621dt0OHDiE6Oho9evSAh4cHIiMjsWHDBvV2W9evWbNm+O2333D37l0AwPXr13H+/Hl06NABgO3rVxpT6XLx4kU4OTmhcePG6jFNmjSBk5OTVembl5cHhmHg7OwMwPZ1UyqVGDBgAOLi4lCnTp0y221ZP6VSiaNHjyI0NBTt27eHh4cHGjdurDENZMv6GYNNGSivXr2CQqGAp6enxnpPT09kZGRYSCrDIYRgwoQJaNasGSIiIgBALX95umVkZMDOzg4uLi46x1iKXbt2ISkpCQkJCWW22bpuDx8+xNq1axESEoJff/0Vw4cPx9ixY7F161YAtq/flClT0KdPH9SqVQtcLheRkZEYN24c+vTpA8D29SuNqXTJyMiAh4dHmeN7eHhYjb7FxcWYOnUq+vbtq+5+a+u6LVy4EBwOB2PHjtW63Zb1y8zMRGFhIRYsWIDY2FgcP34cXbt2Rbdu3XDmzBkAtq2fMXAsLYAxMAyj8TchpMw6a2b06NG4ceMGzp8/X2abMbpZWv8nT57gyy+/xPHjx8Hn83WOs0XdgJI3m+joaMyfPx8AEBkZiZSUFKxduxYDBw5Uj7NV/Xbv3o0ffvgBO3bsQJ06dXDt2jWMGzcOPj4+GDRokHqcreqnDVPoom28tegrk8nQu3dvKJVKrFmzpsLxtqBbUlISVqxYgStXrhgshy3opwpK/+STTzB+/HgAQIMGDXDhwgWsW7cOLVu21LmvLehnDDblQXF3dwebzS5jBWZmZpZ5I7JWxowZg0OHDuH333+Hr6+ver2XlxcAlKubl5cXpFIpcnJydI6xBElJScjMzERUVBQ4HA44HA7OnDmDlStXgsPhqGWzRd0AwNvbG7Vr19ZYFx4ero6st+XvDgDi4uIwdepU9O7dG3Xr1sWAAQMwfvx4tTfM1vUrjal08fLywsuXL8sc/59//rG4vjKZDD179kRaWhpOnDih9p4Atq3buXPnkJmZCX9/f/V9Jj09HRMnTkRgYCAA29bP3d0dHA6nwnuNrepnDDZloNjZ2SEqKgonTpzQWH/ixAk0bdrUQlLpByEEo0ePxr59+3Dq1CkEBQVpbA8KCoKXl5eGblKpFGfOnFHrFhUVBS6XqzHmxYsXuHnzpkX1b9OmDZKTk3Ht2jX1Eh0djX79+uHatWuoUaOGzeoGAO+//36ZlPC7d+8iICAAgG1/dwBQVFQEFkvzVsBms9VvdLauX2lMpct7772HvLw8/PXXX+oxf/75J/Ly8iyqr8o4uXfvHk6ePAk3NzeN7bas24ABA3Djxg2N+4yPjw/i4uLw66+/ArBt/ezs7NCoUaNy7zW2rJ9RmDcmt/Ko0ow3btxIbt26RcaNG0eEQiF59OiRpUUrlxEjRhAnJydy+vRp8uLFC/VSVFSkHrNgwQLi5ORE9u3bR5KTk0mfPn20pj/6+vqSkydPkitXrpAPPvjAKlJV36Z0Fg8htq3bX3/9RTgcDpk3bx65d+8e2b59O7G3tyc//PCDeowt6zdo0CBSvXp1dZrxvn37iLu7O5k8ebJ6jC3pV1BQQK5evUquXr1KAJClS5eSq1evqjNZTKVLbGwsqVevHrl48SK5ePEiqVu3bpWncpanm0wmI507dya+vr7k2rVrGvcZiURi9bpVpJ823s7iIcS29du3bx/hcrkkMTGR3Lt3j6xatYqw2Wxy7tw5m9DP1NicgUIIIatXryYBAQHEzs6ONGzYUJ2qa80A0Lps3rxZPUapVJJZs2YRLy8vwuPxSIsWLUhycrLGccRiMRk9ejRxdXUlAoGAdOrUiTx+/NjM2lTM2waKret2+PBhEhERQXg8HqlVqxZJTEzU2G7L+uXn55Mvv/yS+Pv7Ez6fT2rUqEFmzJih8VCzJf1+//13rb+1QYMGmVSXrKws0q9fPyISiYhIJCL9+vUjOTk5FtMtLS1N533m999/t3rdKtJPG9oMFFvXb+PGjaRmzZqEz+eT+vXrkwMHDtiMfqaGIYSQqvXRUCgUCoVCoRiGTcWgUCgUCoVC+W9ADRQKhUKhUChWBzVQKBQKhUKhWB3UQKFQKBQKhWJ1UAOFQqFQKBSK1UENFAqFQqFQKFYHNVAoFAqFQqFYHdRAoVAoFAqFYnVQA4VCoVAoFIrVQQ0UCoVCoVAoVgc1UCgUCoVCoVgd/w9dxlD6wC2G/gAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "识别结果: 2022210839\n"
     ]
    }
   ],
   "source": [
    "# 加载并预处理图片\n",
    "image_path = 'example.png'\n",
    "binary_image = preprocess_image(image_path)\n",
    "# 分割数字\n",
    "bounding_boxes = segment_digits(binary_image)\n",
    "# 可视化分割结果\n",
    "image_with_boxes = cv2.cvtColor(binary_image, cv2.COLOR_GRAY2BGR)\n",
    "for box in bounding_boxes:\n",
    "    x, y, w, h = box\n",
    "    cv2.rectangle(image_with_boxes, (x, y), (x+w, y+h), (0, 255, 0), 2)\n",
    "plt.imshow(image_with_boxes)\n",
    "plt.show()\n",
    "# 预测数字\n",
    "predictions = predict_digits(binary_image, bounding_boxes)\n",
    "# 输出结果\n",
    "print(f\"识别结果: {''.join(map(str, predictions))}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "DL",
   "language": "python",
   "name": "dl"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
